using System.Linq;
using System.Threading.Tasks;
using DailyPoetryX.AzureStorage.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace DailyPoetryX.AzureStorage.Services {
    /// <summary>
    /// 授权帮助类。
    /// </summary>
    public static class AuthorizationHelper {
        /// <summary>
        /// 授权。
        /// </summary>
        /// <param name="authenticationService">身份验证服务。</param>
        /// <param name="authorizationService">授权服务。</param>
        /// <returns></returns>
        public async static Task<AuthorizationHelperResult> Authorize(
            HttpRequest req, ILogger log,
            IAuthenticationService authenticationService,
            IAuthorizationService authorizationService) {
            var authorizationHeader =
                req.Headers["Authorization"].FirstOrDefault();
            log.LogInformation("Validating token: " + authorizationHeader);

            if (authorizationHeader == null ||
                !authorizationHeader.StartsWith("Bearer")) {
                log.LogInformation(
                    $"Wrong authorization header: {authorizationHeader}");
                return new AuthorizationHelperResult {
                    ActionResult = new UnauthorizedResult()
                };
            }

            string bearerToken = authorizationHeader
                .Substring("Bearer ".Length).Trim();
            log.LogInformation("Got token: " + bearerToken);

            var authenticationResult =
                await authenticationService.AuthenticateAsync(bearerToken);
            if (!authenticationResult.Passed) {
                log.LogInformation(
                    $"Authentication not passed: {authenticationResult.Message}");
                return new AuthorizationHelperResult {
                    ActionResult = new UnauthorizedResult()
                };
            }

            var name = authenticationResult.Name;
            log.LogInformation($"Authentication passed, name: ${name}");

            if (!await authorizationService.AuthorizeAsync(name)) {
                log.LogInformation("Authorization not passed.");
                return new AuthorizationHelperResult {
                    ActionResult = new UnauthorizedResult()
                };
            }

            return new AuthorizationHelperResult {
                Passed = true, AuthenticationResult = authenticationResult
            };
        }
    }
}